/*
 * Copyright © 2012 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. 
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners. 
 * See LICENSE.TXT for license information.
 */
package com.nokia.example.sudokumaster;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;

public class ArrowSelector extends View {

    private static final int TEXT_COLOR = 0x00FFFFFF;
    private final Image buttonImage;
    private final Image largeButtonImage;
    private final Listener listener;
    private TiledLayer numberButtons;
    private Sprite cButton;
    private Sprite button1;
    private Sprite button2;
    private Sprite button3;
    private Sprite button4;
    private final int arrowButtonWidth, arrowButtonHeight;
    private final int cButtonWidth, cButtonHeight;
    private int keyPressed;
    private volatile boolean refreshButtons = true;

    public ArrowSelector(int width, int height, Image buttonImage,
            Image largeButtonImage, Listener listener) {
        super(0, 0, width, height);
        this.buttonImage = buttonImage;
        this.largeButtonImage = largeButtonImage;
        this.listener = listener;
        arrowButtonWidth = buttonImage.getWidth() / 2;
        arrowButtonHeight = buttonImage.getHeight();
        cButtonWidth = largeButtonImage.getWidth() / 2;
        cButtonHeight = largeButtonImage.getHeight();
    }

    public void setLeft(int left) {
        super.setLeft(left);
        refreshButtonPositions();
    }

    public void setRight(int right) {
        super.setRight(right);
        refreshButtonPositions();
    }

    public void setWidth(int width) {
        super.setWidth(width);
        refreshButtonPositions();
    }

    public void setTop(int top) {
        super.setTop(top);
        refreshButtonPositions();
    }

    public void setBottom(int bottom) {
        super.setBottom(bottom);
        refreshButtonPositions();
    }

    public void setHeight(int height) {
        super.setHeight(height);
        refreshButtonPositions();
    }

    private void refreshButtonPositions() {
        if (button1 != null) {
            button1.setPosition(button1.getRefPixelX(), top+arrowButtonWidth*2);
        button2.setPosition(button1.getRefPixelX()+arrowButtonWidth, top+arrowButtonWidth*2);
        button3.setPosition(button2.getRefPixelX()+arrowButtonWidth, top+arrowButtonWidth*2);
        button4.setPosition(button2.getRefPixelX(), top-arrowButtonHeight);
        }
        if (cButton != null) {
            cButton.setPosition(button1.getRefPixelX(), top + arrowButtonHeight);
        }
    }

    protected void paint(Graphics g) {
        if (button1 == null || cButton == null) {
            numberButtons = new TiledLayer(3, 3, buttonImage, arrowButtonWidth,
                                           arrowButtonHeight);
            button1 = new Sprite(buttonImage, arrowButtonWidth, arrowButtonHeight);
            button2 = new Sprite(buttonImage, arrowButtonWidth, arrowButtonHeight);
            button3 = new Sprite(buttonImage, arrowButtonWidth, arrowButtonHeight);
            button4 = new Sprite(buttonImage, arrowButtonWidth, arrowButtonHeight);
            cButton = new Sprite(largeButtonImage, cButtonWidth, cButtonHeight);
            refreshButtonPositions();
        }
        if (refreshButtons) {
            refreshButtons();
        }
        button1.setPosition(button1.getRefPixelX(), top+2*arrowButtonWidth);
        button2.setPosition(button1.getRefPixelX()+arrowButtonWidth, top+2*arrowButtonWidth);
        button3.setPosition(button2.getRefPixelX()+arrowButtonWidth, top+2*arrowButtonWidth);
        button4.setPosition(button2.getRefPixelX(), button1.getRefPixelY()-arrowButtonHeight);
        cButton.setPosition(button1.getRefPixelX(), top+3*arrowButtonHeight);
        button1.paint(g);
        button2.paint(g);
        button3.paint(g);
        button4.paint(g);
        cButton.paint(g);
        paintArrows(g);
    }

    private void paintArrows(Graphics g) {
        g.setColor(TEXT_COLOR);
        int x,y;
        x= button1.getX()+15;
        y= button1.getY() + +15;
        g.drawString("<-", x, y, Graphics.HCENTER | Graphics.TOP);
        x= button2.getX()+15;
        y= button2.getY() + +15;
        g.drawString("∨", x, y, Graphics.HCENTER | Graphics.TOP);
        x= button3.getX()+15;
        y= button3.getY() + +15;
        g.drawString("→", x, y, Graphics.HCENTER | Graphics.TOP);
        x= button4.getX()+15;
        y= button4.getY() + +15;
        g.drawString("∧", x, y, Graphics.HCENTER | Graphics.TOP);
        x = cButton.getX() + cButton.getWidth() / 2;
        y = cButton.getY() + cButton.getHeight() / 2 - g.getFont().getHeight() / 2;
        g.drawString("Borrar", x, y, Graphics.HCENTER | Graphics.TOP);
    }

    private void refreshButtons() {
        refreshButtons = false;
        numberButtons.fillCells(0, 0, 3, 3, 1);
        button1.setFrame(0);
        button2.setFrame(0);
        button3.setFrame(0);
        button4.setFrame(0);
        cButton.setFrame(0);
        if (keyPressed > 9) {
            button1.setFrame(1);
            button2.setFrame(1);
            button3.setFrame(1);
            button4.setFrame(1);
            cButton.setFrame(1);
        }
        else if (keyPressed > 0) {
            int col = (keyPressed - 1) % 3;
            int row = (keyPressed - 1) / 3;
            numberButtons.setCell(col, row, 2);
        }
    }

    public void handlePointerEvent(int type, int x, int y) {
        if (!isVisible()) {
            return;
        }
        if (type == View.POINTER_RELEASED) {
            if (hits(x, y)) {
                listener.arrowSelected(getKey(x, y));
            }
        }
        else {
            setKeyPressed(hits(x, y) ? getKey(x, y) : 0);
        }
    }

    private int getKey(int x, int y) {
        if (y < top+2*arrowButtonHeight) {
            int col = Math.min((x - left) / arrowButtonWidth, 2);
            int row = Math.min((y - top) / arrowButtonHeight, 2);
            return col + 3 * row + 1;
        }
        else {
            return 10;
        }
    }

    public void setVisible(boolean visible) {
        super.setVisible(visible);
        setKeyPressed(0);
    }

    public void setKeyPressed(int n) {
        if (keyPressed != n) {
            keyPressed = n;
            refreshButtons = true;
            invalidate();
        }
    }

    public void keyEvent(int type, int key) {
        if (type == KEY_RELEASED) {
            return;
        }
        if (keyPressed > 0) {
            switch (key) {
                case KEY_UP:
                    setKeyPressed((keyPressed - 3 - 1 + 12) % 12 + 1);
                    break;
                case KEY_DOWN:
                    setKeyPressed((keyPressed + 3 - 1) % 12 + 1);
                    break;
                case KEY_LEFT:
                    setKeyPressed(
                            (keyPressed - 1) / 3 * 3 + (keyPressed - 1 + 2) % 3 + 1);
                    break;
                case KEY_RIGHT:
                    setKeyPressed(
                            (keyPressed - 1) / 3 * 3 + (keyPressed + 1 + 2) % 3 + 1);
                    break;
                case KEY_SELECT:
                    if (type == KEY_PRESSED) {
                        listener.arrowSelected(keyPressed);
                    }
                    break;
                default:
                    break;
            }
        }
        else {
            setKeyPressed(5);
        }
    }

    public static interface Listener {
        void arrowSelected(int n);
    }
}
